package com.binguo.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.binguo.common.enums.CardType;
import com.binguo.common.enums.PayStatus;
import com.binguo.common.exception.ServiceException;
import com.binguo.common.util.LoggerUtil;
import com.binguo.helper.FaceHelperV3;
import com.binguo.model.api.vo.CustomerVO;
import com.binguo.model.api.vo.IntranetCustomerVO;
import com.binguo.model.api.vo.OrderVO;
import com.binguo.model.mapper.BinguoOrderMapper;
import com.binguo.model.mapper.CustomerExtendMapper;
import com.binguo.model.mapper.PayCardMapper;
import com.binguo.model.model.*;
import com.binguo.model.repository.*;
import com.binguo.model.wxapi.form.ApiRegisterForm;
import com.binguo.thirdPay.hzShiMing.HZShiMingFaceService;
import com.binguo.thirdPay.hzShiMing.HZShiMingService;
import com.binguo.thirdPay.hzShiMing.SrPayService;
import com.binguo.thirdPay.zy.ZytkService;
import com.github.pagehelper.util.StringUtil;
import com.tencentcloudapi.iai.v20180301.models.Result;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Condition;

import javax.annotation.Resource;
import java.io.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

import static com.binguo.common.exception.ErrorCode.*;


/**
 * Created by haibang on 18/5/7.
 */
@Service
public class CustomerService {

    @Autowired
    FaceHelperV3 faceHelperV3;

    @Autowired
    CustomerRepository customerRepository;

    @Autowired
    DiscountOrderRepository discountOrderRepository;

    @Autowired
    ProductRepository productRepository;

    @Autowired
    ShopRepository shopRepository;

    @Autowired
    CustomerGroupRepository customerGroupRepository;

    @Autowired
    OrderItemRepository orderItemRepository;

    @Resource
    BinguoOrderMapper binguoOrderMapper;

    @Autowired
    ZytkService zytkService;

    @Autowired
    CustomerExtendRepository customerExtendRepository;

    @Autowired
    PayCardRepository payCardRepository;

    @Autowired
    FaceRepository faceRepository;

    @Autowired
    YpCardRepository ypCardRepository;

    @Autowired
    CashierDeskRepository cashierDeskRepository;

    @Autowired
    CustomerRechargeRepository customerRechargeRepository;

    @Autowired
    HZShiMingService hzShiMingService;

    @Autowired
    HZShiMingFaceService hzShiMingFaceService;

    @Autowired
    ShopService shopService;

    @Autowired
    SrPayService srPayService;

    @Autowired
    BinguoOrderRepository binguoOrderRepository;

    @Autowired
    MonthRechargeRepository monthRechargeRepository;

    @Resource
    PayCardMapper payCardMapper;

    @Autowired
    YpCardService ypCardService;

    @Resource
    CustomerExtendMapper customerExtendMapper;

    public Customer findByCustomerId(Integer customerId) {
        return customerRepository.findById(customerId);
    }


    public Optional<Customer> findCustomerByOpenId(String openId){
        Condition condition = new Condition(Customer.class);
        condition.or().andEqualTo("openid", openId);
        return customerRepository.findByCondition(condition).stream().findFirst();
    }

    public Optional<Customer> findCustomerByOrderingOpenId(String openId){
        Condition condition = new Condition(Customer.class);
        condition.or().andEqualTo("openidOrdering", openId);
        return customerRepository.findByCondition(condition).stream().findFirst();
    }

    public Optional<Customer> findCustomerByShopCustomerID(String shopCustomerID){
        Condition condition = new Condition(Customer.class);
        condition.or().andEqualTo("shop_customerID", shopCustomerID);
        return customerRepository.findByCondition(condition).stream().findFirst();
    }





    public CustomerVO findByFaceNew(Integer shopId, String faceUrl){

        Shop shop = shopService.findShopById(shopId);


        Result[] results = FaceHelperV3.searchFacesFromSingleShop(faceUrl, shopId.toString());

        Integer customerId = null;
        if (results != null && results.length > 0) {
            for (Result result : results) {
                //验证成功策略：confidence值大于90
                if (result.getCandidates()[0].getScore() > 90) {
                    String temp = result.getCandidates()[0].getPersonId();
                    if (temp.contains("_")) {
                        customerId = Integer.valueOf(temp.split("_")[1]);
                    } else {
                        customerId = Integer.valueOf(temp);
                    }
                    break;
                }
            }
        }
        if (customerId != null) {
            Customer customer = customerRepository.findById(customerId);

            if (customer != null) {
                Condition condition = new Condition(CustomerExtend.class);
                condition.or().andEqualTo("shopId",shopId)
                        .andEqualTo("customerId", customer.getId());
                List<CustomerExtend> customerExtendList = customerExtendRepository.findByCondition(condition);
                if (customerExtendList != null && customerExtendList.size() > 0) {
                    CustomerExtend customerExtend = customerExtendList.get(0);
                    if (customerExtend.getIsAudit() == 0) {
                        if (shop.getPayType() == 9){
                            return null;
                        }else {
                            throw new ServiceException(CUSTOMER_NOT_EXIST);
                        }
                    }
                } else {
                    if (shop.getPayType() == 9){
                        return null;
                    }if (shop.getPayType() == 19){
                        CustomerVO customerVO = new CustomerVO();
                        customerVO.setCustomerId(customerId);
                        customerVO.setName(customer.getName());
                        customerVO.setCardNo(customerId.toString());
                        return customerVO;
                    }else {
                        throw new ServiceException(CUSTOMER_NOT_EXIST);
                    }
                }
                CustomerVO customerVO = new CustomerVO();
                customerVO.setCustomerId(customerId);
                customerVO.setName(customer.getName());
                customerVO.setPhone(displayPhone(customer.getPhone()));


                List<PayCard> payCardList = findPayCardList(shopId, customerId);

                AtomicReference<PayCard> yktPayCard = new AtomicReference<>();;
                AtomicReference<PayCard> virtualPayCard = new AtomicReference<>();;
                AtomicReference<Long> accountBalance = new AtomicReference<>(0l);
                if (payCardList != null && payCardList.size() > 0) {
                    payCardList.stream().forEach(payCard -> {
                        if (payCard.getCardtype() == CardType.YKT_CARD.getCode().byteValue()) {
                            yktPayCard.set(payCard);
                        }
                        if (payCard.getCardtype() == CardType.BINGUO_CARD.getCode().byteValue()) {
                            virtualPayCard.set(payCard);
                        }
                        accountBalance.updateAndGet(v -> v + payCard.getAccountbalance() + payCard.getWxAccountbalance() + payCard.getYktAccountbalance() + payCard.getBzAccountbalance());
                    });
                    customerVO.setAccountBalance(accountBalance.get());
                }

                if (yktPayCard.get() != null && StringUtils.hasText(yktPayCard.get().getCardno())) {
                    customerVO.setIsBinding(1);
                    customerVO.setCardNo(yktPayCard.get().getCardno());
                    if (shop.getPayType() == 6) {
                        customerVO.setVipLevel("9");
                    }
                } else {
                    if (virtualPayCard.get() != null) {
                        customerVO.setCardNo(virtualPayCard.get().getCardno());
                    }
                    customerVO.setIsBinding(0);
                }

                return customerVO;
            }
        }
        /*
        if (shop.getPayType() == 6 || shop.getPayType() == 7 || shop.getPayType() == 8) {
            //乐天商户未识别人脸时，创建新人脸
            //区政府同样创建人脸
            int score = FaceHelperV3.detectFace(faceUrl);

            if (score > 70) {//人脸质量分>70，创建临时人脸
                customerId = createPerson(shopId, faceUrl);
            } else {
                throw new ServiceException(CUSTOMER_NOT_EXIST);
            }
            CustomerVO customerVO = new CustomerVO();
            customerVO.setCustomerId(customerId);
            customerVO.setAccountBalance(0l);
            customerVO.setIsBinding(0);

            return customerVO;
        }*/

        if (shop.getPayType() == 9){
            return null;
        }else {
            throw new ServiceException(CUSTOMER_NOT_EXIST);
        }
    }

    public CustomerVO findByShiMingFace(String imgBase64){

        JSONObject faceResult = hzShiMingFaceService.queryFace(imgBase64);

        if (faceResult == null){
            return null;
        }
        String imgToken = faceResult.getString("smkFaceToken");

        JSONObject result = hzShiMingService.faceQuery(imgToken);
        if (result == null){
            return null;
        }
        String SMKPayCardID = result.getString("cardNo");
        Condition condition = new Condition(Customer.class);
        condition.or().andEqualTo("shopPaycardid", SMKPayCardID);
        List<Customer> customerList = customerRepository.findByCondition(condition);
        Customer customer = customerList.get(0);
        customer.setShopPaycardid(SMKPayCardID);
        customer.setIdcardNum(result.getString("certNo"));
        customer.setName(result.getString("olderName"));
        customer.setImageToken(imgToken);
        customer.setCustomerType(result.getString("cardKind"));
        customerRepository.update(customer);
        CustomerVO customerVO = new CustomerVO();
        customerVO.setCardNo(customer.getShopPaycardid());
        customerVO.setCustomerId(customer.getId());
        customerVO.setName(customer.getName());
        return customerVO;
    }

    public static void main(String[] args) {
        //FaceHelperV3.createPerson("96", "96_151", "http://img.binguoai.com/tmp_8f7c191ef8ebcd78320cd414659132e86b673ad1d202dc22.jpg");
        /*String url = "http://img.binguoai.com/62__POS_1.1.4_5343319707317071673.jpg";

        FaceConfidenceV2 faceConfidence = new FaceHelperV2().faceIdentify(url, "62".toString());

        System.out.println(faceConfidence);*//*

        Result[] results = FaceHelperV3.searchFacesFromSingleShop("http://img.binguoai.com/tmp_4f7a2e723b66b469e79d0a306f07b676d7fe3347370107bf.jpg", "114");

        /*String card_id = "85E6EFAD2108040002DCEC650732561D";
        card_id = card_id.substring(0, 8);
        System.out.println(card_id);
        String card_id_1 = card_id.substring(0, 2);
        String card_id_2 = card_id.substring(2, 4);
        String card_id_3 = card_id.substring(4, 6);
        String card_id_4 = card_id.substring(6, 8);
        String newCard_id = card_id_4 + card_id_3 + card_id_2 + card_id_1;
        System.out.println(newCard_id);
        Long valueTen2 = Long.parseLong(newCard_id, 16);
        System.out.println(valueTen2);
        String faceId = FaceHelperV3.createPerson("114", "114_3799", "http://img.binguoai.com/tmp_4f7a2e723b66b469e79d0a306f07b676d7fe3347370107bf.jpg");
        */
        Calendar calendar = Calendar.getInstance();
        System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
        System.out.println(calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
    }

    public String displayPhone(String phone) {
        if (phone != null && phone.length() == 11) {
            phone = phone.substring(0, 3) + "****" + phone.substring(7, 11);
        }

        return phone;
    }


    public CustomerVO findByFace(Integer shopId, String faceUrl){
        Result[] results = FaceHelperV3.searchFacesFromSingleShop(faceUrl, shopId.toString());

        //验证成功策略：confidence值大于90
        Integer customerId = null;
        if (results != null && results.length > 0) {
            for (Result result : results) {
                //验证成功策略：confidence值大于90
                if (result.getCandidates()[0].getScore() > 90) {
                    String temp = result.getCandidates()[0].getPersonId();
                    if (temp.contains("_")) {
                        customerId = Integer.valueOf(temp.split("_")[1]);
                    } else {
                        customerId = Integer.valueOf(temp);
                    }
                    System.out.println("customerId:" + customerId);

                    break;
                }
            }
        }
        //验证成功策略：confidence值大于90
        if(customerId != null){
            Customer customer = customerRepository.findById(customerId);

            if(customer == null) {
                throw new ServiceException(CUSTOMER_NOT_EXIST);
            }
            CustomerVO customerVO = new CustomerVO();
            customerVO.setCustomerId(customerId);
            customerVO.setName(customer.getName());
            customerVO.setPhone(displayPhone(customer.getPhone()));
            Optional<PayCard> cardOptional = findPayCard(shopId, customerId);
            if (cardOptional.isPresent()) {
                customerVO.setCardNo(cardOptional.get().getCardno());
                customerVO.setAccountBalance(cardOptional.get().getAccountbalance());
            } else {
                throw new ServiceException(CUSTOMER_NOT_EXIST);
            }
            return customerVO;
        } else {
            throw new ServiceException(FACE_IDENTIFY);
        }
    }


    public Optional<PayCard> findPayCard(Integer shopId, Integer customerId){
        Condition condition = new Condition(PayCard.class);
        condition.or()
                .andEqualTo("shopid", shopId)
                .andEqualTo("customerid", customerId)
                .andEqualTo("deleted", false)
                .andEqualTo("cardtype", CardType.BINGUO_CARD.getCode().byteValue());
//                .andEqualTo("isnopasswordpay", true);
        //fixme haibang 接入微信免秘支付时开启
        return payCardRepository.findByCondition(condition).stream().findFirst();

    }
    public Optional<PayCard> findYKTPayCard(Integer shopId, Integer customerId){
        Condition condition = new Condition(PayCard.class);
        condition.or()
                .andEqualTo("shopid", shopId)
                .andEqualTo("customerid", customerId)
                .andEqualTo("deleted", false)
                .andEqualTo("cardtype", CardType.YKT_CARD.getCode().byteValue());
//                .andEqualTo("isnopasswordpay", true);
        //fixme haibang 接入微信免秘支付时开启
        return payCardRepository.findByCondition(condition).stream().findFirst();

    }

    public List<PayCard> findPayCardList(Integer shopId, Integer customerId){
        Condition condition = new Condition(PayCard.class);
        condition.or()
                .andEqualTo("shopid", shopId)
                .andEqualTo("customerid", customerId)
                .andEqualTo("deleted", false);

        return payCardRepository.findByCondition(condition);

    }

    public Optional<PayCard> findPayCard(Integer cardId){
        Condition condition = new Condition(PayCard.class);
        condition.or()
                .andEqualTo("id", cardId);
        return payCardRepository.findByCondition(condition).stream().findFirst();

    }

    public PayCard findPayCard(Integer shopId,
                               String cardNo){
        Condition condition = new Condition(PayCard.class);
        condition.or().andEqualTo("shopid",shopId)
                .andEqualTo("cardno", cardNo)
                .andEqualTo("deleted",0);

        List<PayCard> payCardList = payCardRepository.findByCondition(condition);
        if (null == payCardList || payCardList.size() == 0){
            return null;
        }else {
            return payCardList.get(0);
        }
    }

    public Customer getCustomerByPhone(String phoneNum) {
        Condition condition = new Condition(Customer.class);
        condition.or().andEqualTo("phone", phoneNum);
        List<Customer> customerList = customerRepository.findByCondition(condition);
        if (null == customerList || customerList.size() == 0) {
            return null;
        }
        return customerList.get(0);
    }

    public Shop getShopByPhone(String phoneNum) {
        Condition condition = new Condition(Shop.class);
        condition.or().andEqualTo("phone", phoneNum);
        List<Shop> shopList = shopRepository.findByCondition(condition);
        if (null == shopList || shopList.size() == 0) {
            throw new ServiceException(SHOP_NOT_EXISTS);
        }
        return shopList.get(0);
    }

    public PayCard getCustomerPayCard(Integer customerID,
                                      Integer shopID) {
        Condition condition = new Condition(PayCard.class);
        condition.or().andEqualTo("customerid", customerID)
                .andEqualTo("shopid", shopID);
        List<PayCard> payCardList = payCardRepository.findByCondition(condition);
        if (null == payCardList || payCardList.size() == 0) {
            return null;
        }
        return payCardList.get(0);
    }

    public CustomerExtend getCustomerExtend(Integer customerID,
                                            Integer shopID){
        Condition condition = new Condition(CustomerExtend.class);
        condition.or().andEqualTo("customerId", customerID)
                .andEqualTo("shopId", shopID);
        List<CustomerExtend> customerExtendList = customerExtendRepository.findByCondition(condition);
        if (null == customerExtendList || customerExtendList.size() == 0) {
            throw new ServiceException(WX_PAYCARD_NOT_EXIST);
        }
        return customerExtendList.get(0);
    }

    public void deletePerson(Integer customerID,Integer shopID){
        Condition condition = new Condition(CustomerExtend.class);
        condition.or().andEqualTo("customerId",customerID)
                .andEqualTo("shopId",shopID);
        customerExtendRepository.deleteByCondition(condition);

        condition = new Condition(PayCard.class);
        condition.or().andEqualTo("customerid",customerID)
                .andEqualTo("shopid",shopID);
        payCardRepository.deleteByCondition(condition);

        condition = new Condition(Face.class);
        condition.or().andEqualTo("customerId",customerID)
                .andEqualTo("persionid",shopID + "_" + customerID);
        faceRepository.deleteByCondition(condition);

        customerRepository.deleteById(customerID);

        FaceHelperV3.deletePersonFromShop(shopID.toString(),customerID.toString());

    }


    private String post(JSONObject json, String path) {
        HttpClient client = HttpClients.createDefault();
        // 要调用的接口方法
        String url = path;
        HttpPost post = new HttpPost(url);
        JSONObject jsonObject = null;
        try {
            StringEntity s = new StringEntity(json.toString(), "UTF-8");
            //s.setContentEncoding("UTF-8");//此处测试发现不能单独设置字符串实体的编码，否则出错！应该在创建对象时创建
            s.setContentType("application/json");
            post.setEntity(s);
            post.addHeader("content-type", "application/json;charset=UTF-8");
            HttpResponse res = client.execute(post);
            if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 返回json格式：
                jsonObject = JSONObject.parseObject(EntityUtils.toString(res.getEntity()));
            }
        } catch (Exception e) {
            System.out.println("服务间接口调用出错！");
            e.printStackTrace();
            //throw new RuntimeException(e);
        }
        System.out.println(jsonObject.toString());
        return jsonObject.toString();
    }

    public PayCard createPayCard(Integer customerId,Integer shopId){
        Shop shop = shopService.findShopById(shopId);
        CustomerExtend customerExtend = new CustomerExtend();
        customerExtend.setGroupId(0);
        customerExtend.setGroupName("普通会员");
        customerExtend.setIsAudit(1);
        customerExtend.setCustomerId(customerId);
        customerExtend.setShopId(shop.getId());
        customerExtend.setUserStatus(1);
        customerExtendRepository.save(customerExtend);
        PayCard payCard = new PayCard();
        payCard.setCustomerid(customerId);
        payCard.setShopid(shop.getId());
        payCard.setCardtype(CardType.BINGUO_CARD.getCode().byteValue());
        payCard.setName(shop.getName()+"就餐卡");
        payCard.setIsmaster(true);
        payCardRepository.save(payCard);
        return payCard;
    }


    private Integer createPerson(Integer shopId, String faceUrl) {
        Customer customer = new Customer();
//        String customerID = shopId + "_" + customerId;
//        customer.setShop_customerID(customerID);
        customer.setName("尊贵的用户");
        customerRepository.save(customer);


        CustomerExtend customerExtend = new CustomerExtend();
        customerExtend.setShopId(Integer.valueOf(shopId));
        customerExtend.setCustomerId(customer.getId());
        customerExtend.setUserStatus(1);

        customerExtendRepository.save(customerExtend);

        PayCard payCard = new PayCard();
        payCard.setShopid(shopId);
        payCard.setCustomerid(customer.getId());
        payCard.setCardtype(CardType.YKT_CARD.getCode().byteValue());
        payCardRepository.save(payCard);

        String faceId = FaceHelperV3.createPerson(shopId.toString(),
                shopId + "_" + customer.getId().toString(), faceUrl);
        Face face = new Face();
        face.setFaceid(faceId);
        face.setFaceurl(faceUrl);
        face.setPersionid(shopId + "_" + customer.getId().toString());
        face.setCustomerId(customer.getId());
        faceRepository.save(face);

        return customer.getId();
    }


    public JSONObject createYpCustomerBySMK(String certNo,
                                            String name,
                                            String cardNo,
                                            String cardKind,
                                            String image,
                                            String phoneNo) {
        JSONObject result = srPayService.faceBinding(certNo, name, cardNo, cardKind, image, phoneNo);
        String success = result.getString("success");
        String srSuccess = "true";
        if (srSuccess.equals(success)) {
            Customer customer = findSMKCustomer(certNo);
            if (null == customer) {
                customer = new Customer();
                customer.setShopPaycardid(cardNo);
                customer.setIdcardNum(certNo);
                customer.setName(name);
                customer.setPhone(phoneNo);
                customer.setCustomerType(cardKind);
                customerRepository.save(customer);
            } else {
                customer.setShopPaycardid(cardNo);
                customer.setCustomerType(cardKind);
                customer.setName(name);
                customer.setPhone(phoneNo);
                customerRepository.update(customer);
            }
        }
        return result;
    }

    public Customer findSMKCustomer(String certNo) {
        Condition condition = new Condition(Customer.class);
        condition.or().andEqualTo("idcardNum", certNo);
        List<Customer> customerList = customerRepository.findByCondition(condition);
        if (null == customerList || customerList.size() == 0) {
            return null;
        } else {
            return customerList.get(0);
        }
    }

    public Customer findSMKCustomerByCardNo(String cardNo) {
        Condition condition = new Condition(Customer.class);
        condition.or().andEqualTo("shopPaycardid", cardNo);
        List<Customer> customerList = customerRepository.findByCondition(condition);
        if (null == customerList || customerList.size() == 0) {
            return null;
        } else {
            return customerList.get(0);
        }
    }

    public String getSMKAcountBalance(Customer customer){
        Long SMKAccountBalance = 0L;
        //餐台钱包
        String YFKType = "000";
        //重阳分
        String CYFType = "101";
        //金夕分
        String JXFType = "106";
        Boolean type = false;
        JSONObject result = hzShiMingService.queryAcc(customer.getShopPaycardid(),customer.getIdcardNum(),customer.getCustomerType());
        if (result != null) {
            JSONArray subAccList = result.getJSONArray("subAccList");
            for (int i = 0; i < subAccList.size(); i++) {
                JSONObject SMKBalance = subAccList.getJSONObject(i);
                String accType = SMKBalance.getString("accType");
                if (accType.equals(YFKType)) {
                    type = true;
                    SMKAccountBalance += SMKBalance.getLong("balance");
                }
                if (accType.equals(CYFType)) {
                    type = true;
                    SMKAccountBalance += SMKBalance.getLong("balance");
                }
                if (accType.equals(JXFType)) {
                    type = true;
                    SMKAccountBalance += SMKBalance.getLong("balance");
                }
            }
        }
        if (type) {
            return SMKAccountBalance.toString();
        }else {
            return null;
        }
    }

    public PayCard getYpCard(String cardId,Integer shopId){
        Condition ypCondition = new Condition(YpCard.class);
        ypCondition.or().andEqualTo("cardId",cardId)
                .andEqualTo("shopId", shopId);
        List<YpCard> ypCardList = ypCardRepository.findByCondition(ypCondition);
        if (null == ypCardList || ypCardList.size() == 0) {
            throw new ServiceException(CUSTOMER_NOT_EXIST);
        }
        YpCard ypCard = ypCardList.get(0);
        if (ypCard.getStatus() != 1) {
            throw new ServiceException(CUSTOMER_NOT_EXIST);
        }
        String cardNo = ypCard.getCardNo();

        Condition payCardCondition = new Condition(PayCard.class);
        payCardCondition.or().andEqualTo("cardno", cardNo)
                .andEqualTo("shopid", shopId)
                .andEqualTo("deleted",0);
        List<PayCard> payCardList = payCardRepository.findByCondition(payCardCondition);
        if (null == payCardList || payCardList.size() == 0) {
            throw new ServiceException(CUSTOMER_NOT_EXIST);
        }
        PayCard payCard = payCardList.get(0);
        return payCard;
    }

    public YpCard getYpCardByCardNo(String cardNo,
                                    Integer shopId){
        Condition ypCondition = new Condition(YpCard.class);
        ypCondition.or().andEqualTo("cardNo",cardNo)
                .andEqualTo("shopId", shopId);
        List<YpCard> ypCardList = ypCardRepository.findByCondition(ypCondition);
        if (null == ypCardList || ypCardList.size() == 0) {
            return null;
        }
        return ypCardList.get(0);
    }

    public void rechargeByMonthDay(){
        Integer rechargeType;
        Calendar calendar = Calendar.getInstance();
        Integer day = calendar.get(Calendar.DAY_OF_MONTH);
        Integer hour = calendar.get(Calendar.HOUR_OF_DAY);
        Integer monthEndDay =  calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        Condition condition = new Condition(MonthRecharge.class);
        List<MonthRecharge> monthRechargeList;
        if (day.equals(monthEndDay)){
            condition.or().andEqualTo("day",0)
                    .andEqualTo("hour",hour)
                    .andEqualTo("status",1);
            monthRechargeList = monthRechargeRepository.findByCondition(condition);
            if (day.equals(28)){
                condition.clear();
                condition.or().andEqualTo("day",day)
                        .andEqualTo("hour",hour)
                        .andEqualTo("status",1);
            }
            monthRechargeList.addAll(monthRechargeRepository.findByCondition(condition));
        }else {
            condition.or().andEqualTo("day",day)
                    .andEqualTo("hour",hour)
                    .andEqualTo("status",1);
            monthRechargeList = monthRechargeRepository.findByCondition(condition);
        }
        List<PayCard> payCardList;
        for (MonthRecharge monthRecharge : monthRechargeList){
            List<Integer> customerIDList = new ArrayList<>();
            if (monthRecharge.getGroupId().equals(-1)){
                Condition payCardCondition = new Condition(PayCard.class);
                payCardCondition.or().andEqualTo("shopid",monthRecharge.getShopId())
                        .andEqualTo("cardtype",0)
                        .andEqualTo("deleted",0);
                payCardList = payCardRepository.findByCondition(payCardCondition);
                for (PayCard payCard : payCardList){
                    customerIDList.add(payCard.getCustomerid());
                }
            }else {
                customerIDList = payCardMapper.getCustomerIDListByGroupID(monthRecharge.getShopId(),monthRecharge.getGroupId());
                payCardList = payCardMapper.getPayCardListByGroupID(monthRecharge.getShopId(),customerIDList);
            }
            if (monthRecharge.getType().equals(1)) {
                payCardMapper.updatePayCardByCustomer(customerIDList, monthRecharge.getMoney().intValue(), monthRecharge.getShopId());
                rechargeType = 15;
            }else {
                payCardMapper.clearPayCardByCustomer(customerIDList,monthRecharge.getShopId());
                rechargeType = 17;
            }
            for (PayCard payCard : payCardList){
                CustomerRecharge customerRecharge = new CustomerRecharge();
                Customer customer = customerRepository.findById(payCard.getCustomerid());
                CustomerExtend customerExtend = getCustomerExtend(payCard.getCustomerid(),payCard.getShopid());
                Long amount = payCard.getAccountbalance()+payCard.getBzAccountbalance()+payCard.getWxAccountbalance()+payCard.getYktAccountbalance();
                customerRecharge.setRechargeType(rechargeType);
                if (rechargeType.equals(15)) {
                    customerRecharge.setRechargeMoney(monthRecharge.getMoney().intValue());
                }else {
                    customerRecharge.setRechargeMoney(payCard.getBzAccountbalance().intValue());
                }
                customerRecharge.setRechargeDate(new Date());
                customerRecharge.setRechargeCustomerGroupid(customerExtend.getGroupId());
                customerRecharge.setRechargeShopid(monthRecharge.getShopId());
                customerRecharge.setRechargeCustomerName(customer.getName());
                customerRecharge.setRechargeCustomerPhone(customer.getPhone());
                customerRecharge.setRechargeCardAmount(amount);
                customerRecharge.setRechargeCustomerid(customer.getId());
                customerRechargeRepository.save(customerRecharge);
                BinguoOrder binguoOrder= new BinguoOrder();
                binguoOrder.setCardno(payCard.getCardno());
                binguoOrder.setCardid(payCard.getId());
                binguoOrder.setBzMoney(monthRecharge.getMoney());
                if (rechargeType.equals(15)) {
                    binguoOrder.setOrdertype(7);
                }else {
                    binguoOrder.setOrdertype(8);
                }
                createRechargeOrder(customerRecharge,binguoOrder);
            }
        }
    }
    public JSONObject getIntranetCustomerList(Integer shopId,
                                              Integer pageNum){
        JSONObject result = new JSONObject();
        Condition condition = new Condition(PayCard.class);
        condition.or().andEqualTo("shopid",shopId)
                .andEqualTo("deleted",0);
        List<PayCard> payCardList = payCardRepository.findByCondition(condition);

        result.put("count",payCardList.size());

        List<IntranetCustomerVO> intranetCustomerVOList = new ArrayList<>();
        List<String> faceImgUrlList;
        Customer customer;
        IntranetCustomerVO intranetCustomerVO;
        payCardList = payCardMapper.getUpdatePaycardList(shopId,pageNum);
        if (payCardList != null && payCardList.size() > 0){
            for (PayCard payCard : payCardList){
                intranetCustomerVO = new IntranetCustomerVO();
                customer = customerRepository.findById(payCard.getCustomerid());
                intranetCustomerVO.setCustomer(customer);
                String persionId = shopId + "_" + customer.getId();

                faceImgUrlList = new ArrayList<>();
                Condition faceCondition = new Condition(Face.class);
                faceCondition.or().andEqualTo("persionid",persionId);
                List<Face> faceList = faceRepository.findByCondition(faceCondition);
                if (faceList != null && faceList.size() > 0){
                    for (Face face : faceList){
                        faceImgUrlList.add(face.getFaceurl());
                    }
                }
                intranetCustomerVO.setFaceImgUrlList(faceImgUrlList);
                intranetCustomerVOList.add(intranetCustomerVO);
            }
        }
        result.put("intranetCustomerVOList",intranetCustomerVOList);

        return result;
    }

    public JSONObject getIntranetCustomer(Integer id,Integer shopID){
        JSONObject result = new JSONObject();

        CustomerExtend customerExtend = getCustomerExtend(id, shopID);

        PayCard payCard = getCustomerPayCard(id, shopID);

        result.put("customerExtend",customerExtend);
        result.put("payCard",payCard);
        return result;
    }

    public Customer getCustomerByShopCustomerId(String shopCustomerId){
        Condition condition = new Condition(Customer.class);
        condition.or().andEqualTo("shopCustomerid",shopCustomerId);
        List<Customer> customerList = customerRepository.findByCondition(condition);
        if (null == customerList || customerList.size() == 0){
            return null;
        }else {
            return customerList.get(0);
        }
    }

    public void createRechargeOrder(CustomerRecharge customerRecharge,
                                    BinguoOrder binguoOrder){
        String orderNo = "WEB"+System.currentTimeMillis();
        binguoOrder.setSerialnumber(orderNo);
        binguoOrder.setOrderno(orderNo);
        binguoOrder.setShopid(customerRecharge.getRechargeShopid());
        binguoOrder.setCardno(binguoOrder.getCardno());
        binguoOrder.setCardid(binguoOrder.getCardid());
        binguoOrder.setCustomerid(customerRecharge.getRechargeCustomerid());
        binguoOrder.setCustomergroupid(customerRecharge.getRechargeCustomerGroupid());
        binguoOrder.setCustomername(customerRecharge.getRechargeCustomerName());
        binguoOrder.setCustomerphone(customerRecharge.getRechargeCustomerPhone());
        binguoOrder.setSource(new Byte("1"));
        binguoOrder.setRealfee(customerRecharge.getRechargeMoney().longValue() + customerRecharge.getRechargeDiscountMoney().longValue());
        binguoOrder.setTotalfee(customerRecharge.getRechargeMoney().longValue() + customerRecharge.getRechargeDiscountMoney().longValue());
        binguoOrder.setTotalquantity(1);
        binguoOrder.setPaystatus(new Byte("1"));
        binguoOrder.setRefundstatus(new Byte("0"));
        binguoOrder.setMoney(binguoOrder.getMoney());
        binguoOrder.setBzMoney(binguoOrder.getBzMoney());
        binguoOrder.setYktMoney(binguoOrder.getYktMoney());
        binguoOrder.setWxMoney(binguoOrder.getWxMoney());
        binguoOrderMapper.insertSelective(binguoOrder);
    }

    public Boolean checkGroupName(String name){
        Condition condition = new Condition(CustomerGroup.class);
        condition.or().andEqualTo("groupName",name)
                .andEqualTo("deleted",0);
        List<CustomerGroup> groupList = customerGroupRepository.findByCondition(condition);

        if(groupList == null || groupList.size() == 0){
            return false;
        }else {
            return true;
        }
    }

    public CustomerGroup saveCustomerGroup(String name,
                                           Integer shopId){

        Condition condition = new Condition(CustomerGroup.class);
        condition.or().andEqualTo("groupName",name)
                .andEqualTo("shopId",shopId);

        List<CustomerGroup> groupList = customerGroupRepository.findByCondition(condition);

        if (groupList != null && groupList.size() > 0){
            throw new ServiceException("会员等级名称重复");
        }

        CustomerGroup customerGroup = new CustomerGroup();
        customerGroup.setShopId(shopId);
        customerGroup.setDeleted(0);
        customerGroup.setGroupName(name);

        customerGroupRepository.save(customerGroup);

        return customerGroup;
    }

    public void updateCustomerGroup(String name,
                                    Integer id,
                                    Integer shopId){

        CustomerGroup customerGroup = customerGroupRepository.findById(id);

        if (customerGroup == null){
            throw new ServiceException("groupId 不存在");
        }

        if (!customerGroup.getShopId().equals(shopId)){
            throw new ServiceException("传入的groupId非本店ID");
        }

        Condition condition = new Condition(CustomerGroup.class);
        condition.or().andEqualTo("groupName",name)
                .andNotEqualTo("id",id);

        List<CustomerGroup> customerGroupList = customerGroupRepository.findByCondition(condition);

        if (null != customerGroupList && customerGroupList.size() > 0){
            throw new ServiceException("有重复会员等级名称");
        }

        customerGroup.setGroupName(name);

        customerGroupRepository.update(customerGroup);
    }

    public void customerPay(PayCard payCard,
                            Long realFee,
                            String orderNo){
        BinguoOrder binguoOrder = new BinguoOrder();
        binguoOrder.setOrderno(orderNo);
        binguoOrder.setShopid(payCard.getShopid());
        binguoOrder.setRealfee(realFee);
        binguoOrder.setTotalfee(realFee);
        binguoOrder.setCardid(payCard.getId());
        binguoOrder.setCardno(payCard.getCardno());
        binguoOrder.setCustomerid(payCard.getCustomerid());
        binguoOrder.setOrdertype(12);
        binguoOrder.setSource(new Byte("1"));



        Long balance = payCard.getAccountbalance();
        Long wxBalance = payCard.getWxAccountbalance();
        Long yktBalance = payCard.getYktAccountbalance();
        Long bzBalance = payCard.getBzAccountbalance();

        Long bzNewBalance = bzBalance - realFee;
        Long yktNewBalance = yktBalance - realFee+ bzBalance;
        Long newBalance = balance - realFee + yktBalance + bzBalance;
        Long wxNewBalance = wxBalance - realFee + balance + yktBalance + bzBalance;


        if (bzNewBalance >= 0) {
            payCard.setBzAccountbalance(bzNewBalance);
            binguoOrder.setBzMoney(realFee);
            payCardRepository.update(payCard);
        }else if (yktNewBalance >= 0) {
            payCard.setBzAccountbalance(0L);
            binguoOrder.setBzMoney(bzBalance);
            payCard.setYktAccountbalance(yktNewBalance);
            binguoOrder.setYktMoney(realFee - bzBalance);
            payCardRepository.update(payCard);
        }else if (newBalance >= 0) {
            payCard.setBzAccountbalance(0L);
            binguoOrder.setBzMoney(bzBalance);
            payCard.setYktAccountbalance(0L);
            binguoOrder.setYktMoney(yktBalance);
            payCard.setAccountbalance(newBalance);
            binguoOrder.setMoney(realFee - bzBalance - yktBalance);
            payCardRepository.update(payCard);
        } else if (wxNewBalance >= 0) {
            payCard.setYktAccountbalance(0L);
            binguoOrder.setYktMoney(yktBalance);
            payCard.setAccountbalance(0L);
            binguoOrder.setMoney(balance);
            payCard.setBzAccountbalance(0L);
            binguoOrder.setBzMoney(bzBalance);
            payCard.setWxAccountbalance(wxNewBalance);
            binguoOrder.setWxMoney(realFee - bzBalance - yktBalance - balance);
            payCardRepository.update(payCard);
        } else {
            throw new ServiceException(PAYCARD_NOT_SUFFICIENT_FUNDS);
        }
        binguoOrderRepository.save(binguoOrder);
    }

//    public JSONObject zhaoHangUpDate(ApiRegisterForm form,
//                                     Shop shop){
//
//        JSONObject result = new JSONObject();
//
//        String faceResult = "人脸创建成功";
//
//        String faceResultCode = "000";
//
//        boolean isCustomer = false;
//
//
//        if(StringUtils.hasText(form.getCardNo())){
//            PayCard payCard = findPayCard(shop.getId(),form.getCardNo());
//            if (payCard != null){
//                throw new ServiceException("卡号重复");
//            }
//        }
//
//        Condition condition = new Condition(Customer.class);
//        condition.or().andEqualTo("phone", form.getPhone());
//
//        List<Customer> customerList = customerRepository.findByCondition(condition);
//
//        Customer customer;
//        String faceID = null;
//        if (customerList != null && customerList.size() > 0) {
//            isCustomer = true;
//            customer = customerList.get(0);
//            customer.setName(form.getUsername());
//            customerRepository.update(customer);
//
//            Condition payCardCondition = new Condition(PayCard.class);
//            payCardCondition.or()
//                    .andEqualTo("customerid", customer.getId())
//                    .andEqualTo("shopid", shop.getId())
//                    .andEqualTo("cardtype", CardType.BINGUO_CARD.getCode());
//
//            List<PayCard> payCardList = payCardMapper.selectByCondition(payCardCondition);
//
//            if (payCardList != null && payCardList.size() > 0) {
//                PayCard payCard = payCardList.get(0);
//                if (payCard.getDeleted()) {
//                    payCard.setDeleted(false);
//                    payCardRepository.update(payCard);
//                    Condition customerExtendCondition = new Condition(CustomerExtend.class);
//                    customerExtendCondition.or().andEqualTo("customerId", customer.getId())
//                            .andEqualTo("shopId", shop.getId());
//
//                    List<CustomerExtend> customerExtendList = customerExtendMapper.selectByCondition(customerExtendCondition);
//                    CustomerExtend customerExtend = customerExtendList.get(0);
//                    if (customerExtend.getIsAudit() == 0) {
//                        CustomerExtend temp = new CustomerExtend();
//                        temp.setId(customerExtend.getId());
//                        temp.setIsAudit(1);
//                        customerExtendMapper.updateByPrimaryKeySelective(temp);
//                    }
//                }
//            }else {
//                shopService.createShopPayCard(shop,customer,form.getCardNo());
//            }
//        }else {
//            customer = new Customer();
//            customer.setName(form.getUsername());
//            customer.setCreated(new Date());
//            customer.setUpdated(customer.getCreated());
//            customer.setPhone(form.getPhone());
//            customerRepository.save(customer);
//
//            shopService.createShopPayCard(shop,customer,form.getCardNo());
//        }
//
//        boolean faceAdded = false;
//        if (!StringUtils.isEmpty(form.getFaceUrl())){
//
//            int score = FaceHelperV3.detectFace(shop.getId(), form.getFaceUrl());
//            if (score < 70) {
//                faceResult = "人脸图片质量不合格";
//                faceResultCode = "001";
//            }
//
//            String persionId = shop.getId() + "_" + customer.getId();
//
//            if (isCustomer){
//                FaceHelperV3.deletePerson(persionId);
//                Condition faceCondition = new Condition(Face.class);
//                faceCondition.or().andEqualTo("persionid",persionId);
//                faceRepository.deleteByCondition(faceCondition);
//            }
//
//            Condition tempFaceExample = new Condition(Face.class);
//            tempFaceExample.or().andEqualTo("customerId",customer.getId())
//                    .andEqualTo("persionid", shop.getId() + "_" + customer.getId());
//
//
//            List<Face> faceList = faceRepository.findByCondition(tempFaceExample);
//            if (faceList != null && faceList.size() > 0){
//                for (Face face : faceList){
//                    if (face.getFaceurl().equals(form.getFaceUrl())) {
//                        faceAdded = true;
//                        break;
//                    }
//                }
//                if (!faceAdded){
//                    faceID = FaceHelperV3.addFace(shop.getId() + "_" + customer.getId(), form.getFaceUrl());
//                }
//            } else {
//                faceID = FaceHelperV3.createPerson(String.valueOf(shop.getId()),
//                        shop.getId() + "_" + customer.getId(), form.getFaceUrl());
//            }
//
//        }
//        //此图片未创建
//        if (faceID != null) {
//            Face temp = new Face();
//            temp.setFaceid(faceID);
//            temp.setCustomerId(customer.getId());
//            temp.setFaceurl(form.getFaceUrl());
//            temp.setPersionid(shop.getId() + "_" + customer.getId());
//            faceRepository.save(temp);
//        }else {
//            faceResult = "人脸创建失败";
//            faceResultCode = "002";
//        }
//
//        result.put("faceId",faceID);
//        result.put("faceResultCode",faceResultCode);
//        result.put("faceResult",faceResult);
//        result.put("customerId",customer.getId());
//        return result;
//    }

}
